#pragma once
// #define _GNU_SOURCE
#include <iostream>
using namespace std;
#include "Buffer.h"
#include "HttpResponse.h"
#include <map>
#include <functional>

// #define MSG_SEND_AUTO

enum class reqProcessState : char { // Http请求的解析状态
	_ParseReqLine, _ParseReqHeaders, _ParseReqBody, _ParseReqDone
};

class HttpRequest { // Http请求
public:
	HttpRequest();  // 实例化HttpRequest
	void reset();   // 重置HttpRequest

	reqProcessState getState() { return _curState; }			// 获取解析状态
	void setState(reqProcessState state) { _curState = state; } // 设置解析状态

	void addHeader(const string key, const string value); // 添加请求头键值对
	string getHeader(const string key);                   // 根据key得到value

	// 解析请求行
	bool parseRequestLine(Buffer* readBuf);

	// 解析[记录在Buffer的请求报头]中的某一行, 并存储到_reqHeaders
	bool parseRequestHeader(Buffer* readBuf);

	// 解析http请求, 解析成功会填充response, 并将http响应写入sendBuf
	bool parseHttpRequest(Buffer* readBuf, HttpResponse* response, Buffer* sendBuf, int sockfd);

	// 发送文件: 对应HttpResponse.h的函数指针responseBody
	static void sendFile(string fileName, Buffer* sendBuf, int sockfd); // ������ͨ�ļ�
	static void sendDir(string dirName, Buffer* sendBuf, int sockfd);   // ����Ŀ¼

	// 处理http请求: 解析request，填充response
	bool processRequest(HttpResponse* response);

	void setMethod(string method) { _method = method; }
	void setUrl(string url) { _url = url; }
	void setVersion(string version) { _version = version; }
private:
	// 拆分请求行: 在[start, end)中找到第一个sub的起始地址space, 将[start, space)赋值给*ptr
	char* splitRequestLine(const char* start, const char* end, const char* sub, function<void(string)> callback);

	int hexToDec(char c);						 // 将字符转换为整形数
	string decodeMsg(string msg);				 // 将from译码处理为正确的内容
	const string getFileType(const string name); // 获取文件name对应的Content-Type

	string _method;  // 请求方法
	string _url;     // URL
	string _version; // http协议的版本
	map<string, string> _reqHeaders; // 请求报头记录的多个键值对
	reqProcessState _curState;		 // 当前Http请求的解析状态
};